﻿// -----------------------------------------------------------------------
// <copyright file="XmlReaderExtensions.cs" company="Zen Design Corp">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace Zen.BlackBerry.Common
{
	using System;
	using System.Globalization;
	using System.Xml;
	using System.Xml.Serialization;

	/// <summary>
	/// XML serialization helper methods
	/// </summary>
	public static class XmlExtensions
	{
		/// <summary>
		/// Reads the RIM formatted time from the specified attribute.
		/// </summary>
		/// <param name="reader">The reader.</param>
		/// <param name="attributeName">Name of the attribute.</param>
		/// <returns></returns>
		public static DateTime ReadRimTime(this XmlReader reader, string attributeName)
		{
			return DateTime.ParseExact(
				reader[attributeName],
				"yyyy-MM-dd'T'HH:mm:ss'Z'",
				CultureInfo.InvariantCulture,
				DateTimeStyles.AssumeUniversal);
		}

		/// <summary>
		/// Tries the read RIM formatted time from the specified attribute.
		/// </summary>
		/// <param name="reader">The reader.</param>
		/// <param name="attributeName">Name of the attribute.</param>
		/// <returns></returns>
		public static DateTime? TryReadRimTime(this XmlReader reader, string attributeName)
		{
			string time = reader[attributeName];
			if (string.IsNullOrWhiteSpace(time))
			{
				return null;
			}

			return DateTime.ParseExact(
				time,
				"yyyy-MM-dd'T'HH:mm:ss'Z'",
				CultureInfo.InvariantCulture,
				DateTimeStyles.AssumeUniversal);
		}

		/// <summary>
		/// Writes the RIM formatted time to the specified attribute.
		/// </summary>
		/// <param name="writer">The writer.</param>
		/// <param name="attributeName">Name of the attribute.</param>
		/// <param name="value">The value.</param>
		public static void WriteRimTime(this XmlWriter writer, string attributeName, DateTime value)
		{
			writer.WriteAttributeString(attributeName, value.ToString("yyyy-MM-dd'T'HH:mm:ss'Z'"));
		}

		/// <summary>
		/// Gets the enum value from the specified text.
		/// </summary>
		/// <typeparam name="TEnum">The type of the enum.</typeparam>
		/// <param name="text">The text.</param>
		/// <param name="defaultValue">The default value.</param>
		/// <returns></returns>
		public static TEnum GetEnumFromText<TEnum>(string text, TEnum defaultValue)
		{
			TEnum value = defaultValue;
			if (!string.IsNullOrEmpty(text))
			{
				foreach (var item in typeof(TEnum).GetMembers())
				{
					XmlEnumAttribute[] attrs = (XmlEnumAttribute[])
						item.GetCustomAttributes(typeof(XmlEnumAttribute), false);
					if (attrs.Length > 0)
					{
						if (attrs[0].Name == text)
						{
							value = (TEnum)Enum.Parse(typeof(TEnum), item.Name);
							break;
						}
					}
				}
			}
			return value;
		}

		/// <summary>
		/// Gets the text from specified enum.
		/// </summary>
		/// <typeparam name="TEnum">The type of the enum.</typeparam>
		/// <param name="value">The value.</param>
		/// <returns></returns>
		public static string GetTextFromEnum<TEnum>(TEnum value)
		{
			string memberName = typeof(TEnum).GetEnumName(value);

			foreach (var item in typeof(TEnum).GetMember(memberName))
			{
				XmlEnumAttribute[] attrs = (XmlEnumAttribute[])
					item.GetCustomAttributes(typeof(XmlEnumAttribute), false);
				if (attrs.Length > 0)
				{
					memberName = attrs[0].Name;
					break;
				}
			}

			return memberName;
		}

		/// <summary>
		/// Reads the enum value from the specified attribute.
		/// </summary>
		/// <typeparam name="TEnum">The type of the enum.</typeparam>
		/// <param name="reader">The reader.</param>
		/// <param name="attributeName">Name of the attribute.</param>
		/// <param name="defaultValue">The default value.</param>
		/// <returns></returns>
		public static TEnum ReadEnum<TEnum>(this XmlReader reader, string attributeName, TEnum defaultValue)
		{
			return GetEnumFromText<TEnum>(reader[attributeName], defaultValue);
		}

		/// <summary>
		/// Writes the enum value to the specified attribute.
		/// </summary>
		/// <typeparam name="TEnum">The type of the enum.</typeparam>
		/// <param name="writer">The writer.</param>
		/// <param name="attributeName">Name of the attribute.</param>
		/// <param name="value">The value.</param>
		public static void WriteEnum<TEnum>(this XmlWriter writer, string attributeName, TEnum value)
		{
			writer.WriteAttributeString(attributeName, GetTextFromEnum<TEnum>(value));
		}
	}
}
